home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / alpha.arc / PC.C < prev    next >
C/C++ Source or Header  |  1988-07-26  |  6KB  |  256 lines

  1. /* OS- and machine-dependent stuff for IBM-PC running MS-DOS */
  2. #include <stdio.h>
  3. #include <sgtty.h>
  4. #include "global.h"
  5. #include "mbuf.h"
  6. #include "internet.h"
  7. #include "iface.h"
  8. #include "cmdparse.h"
  9.  
  10. /* This flag is set by setirq() if IRQ 8-15 is used, indicating
  11.  * that the machine is a PC/AT with a second 8259 interrupt controller.
  12.  * If this flag is set, the interrupt return code in pcgen.asm will
  13.  * send an End of Interrupt command to the second 8259 as well as the
  14.  * first.
  15.  */
  16. char isat;    
  17.  
  18. /* Interface list header */
  19. struct interface *ifaces;
  20.  
  21. /* Aztec memory allocation control */
  22. int _STKLOW = 0;    /* Stack above heap */
  23. int _STKSIZ = 16384/16;    /* 16K stack -- overridden in grabcore */
  24. int _HEAPSIZ = 4096/16;    /* Isn't really used */
  25. int _STKRED = 4096;    /* Stack red zone in bytes -- this really matters */
  26.  
  27. char ttbuf[BUFSIZ];
  28.  
  29. /* Called at startup time to set up console I/O, memory heap */
  30. ioinit()
  31. {
  32.     struct sgttyb ttybuf;
  33.     unsigned grabcore();
  34.  
  35.     /* Save these two file table entries for something more useful */
  36.     fclose(stdaux);
  37.     fclose(stdprt);
  38.  
  39.     /* Interrupts use a special stack deep in data space.
  40.      * Calls to sbrk() (invoked by malloc when it needs more memory
  41.      * from the system) at interrupt time will fail because sbrk()
  42.      * will think that the stack has overwritten the heap. So
  43.      * grab all the memory we can now for the heap so that malloc
  44.      * won't have to call sbrk and alloc_mbuf() won't fail unnecessarily
  45.      * at interrupt time.
  46.      */
  47.     grabcore();
  48.  
  49.     setbuf(stdout,ttbuf);
  50.  
  51.     /* Put display in raw mode. Note that this breaks tab expansion,
  52.      * so you need to run NANSI.SYS or equivalent.
  53.      */
  54.     ioctl(1,TIOCGETP,&ttybuf);
  55.     ttybuf.sg_flags = RAW;
  56.     ioctl(1,TIOCSETP,&ttybuf);
  57. }
  58. /* Called just before exiting to restore console state */
  59. iostop()
  60. {
  61.     struct sgttyb ttybuf;
  62.  
  63.     setbuf(stdout,NULLCHAR);
  64.     ioctl(1,TIOCGETP,&ttybuf);
  65.     ttybuf.sg_flags &= ~RAW;
  66.     ioctl(1,TIOCSETP,&ttybuf);
  67.     while(ifaces != NULLIF){
  68.         if(ifaces->stop != NULLFP)
  69.             (*ifaces->stop)(ifaces);
  70.         ifaces = ifaces->next;
  71.     }
  72. }
  73. /* Spawn subshell */
  74. doshell(argc,argv)
  75. {
  76.     char *command,*getenv();
  77.     struct sgttyb ttybuf,ttysav;
  78.     int ret;
  79.  
  80.     ioctl(1,TIOCGETP,&ttysav);
  81.     ioctl(1,TIOCGETP,&ttybuf);
  82.     ttybuf.sg_flags &= ~RAW;
  83.     ioctl(1,TIOCSETP,&ttybuf);
  84.  
  85.     if((command = getenv("COMSPEC")) == NULLCHAR)
  86.         command = "/COMMAND.COM";
  87.     ret = fexecl(command,command,NULLCHAR);
  88.     ioctl(1,TIOCSETP,&ttysav);
  89.     if(ret == -1)
  90.         return -1;
  91.     else
  92.         return wait();
  93. }
  94.  
  95. /* checks the time then ticks and updates ISS */
  96. static short clockstart = 0;
  97. static short clkval = 0;
  98. void
  99. check_time()
  100. {
  101.     int32 iss();
  102.     short ntime;
  103.  
  104.     if(!clockstart){
  105.         /* Executed only once */
  106.         clkval = peekw(0x6c,0x40);
  107.         clockstart = 1;
  108.         return;
  109.     }
  110.     /* Read the low order word of the BIOS tick counter directly. The
  111.      * INT 1Ah call isn't used because it stupidly clears the
  112.      * "midnight passed" flag and we'd have to update the date ourselves.
  113.      * (See Norton, p222).
  114.      * 
  115.       * The PC's time-of-day handling is a real crock of shit. Why not a
  116.      * nice simple long binary count from a fixed UTC epoch, as in UNIX??
  117.      */
  118.     ntime = peekw(0x6c,0x40);
  119.     while(ntime != clkval){    /* Handle possibility of several missed ticks */
  120.         clkval++;
  121.         icmpclk();    /* Call this one before tick */
  122.         tick();
  123.         (void)iss();
  124.     }
  125. }
  126. /* Read characters from the keyboard, translating them to "real" ASCII
  127.  * If none are ready, return the -1 from kbraw()
  128.  */
  129. int
  130. kbread()
  131. {
  132.     int kbraw(),c;
  133.  
  134.     if((c = kbraw()) == 0){
  135.         /* Lead-in to a special char */
  136.         c = kbread();
  137.         switch(c){
  138.         case 3:        /* NULL (bizzare!) */
  139.             c = 0;
  140.             break;
  141.         case 68:    /* F-10 key (used as command-mode escape) */
  142.             c = -2;
  143.             break;
  144.         case 83:    /* DEL key */
  145.             c = 0x7f;
  146.             break;
  147.         default:    /* Dunno what it is */
  148.             c = -1;
  149.         }
  150.     }
  151.     return c;
  152. }
  153. #define    CTLZ    26
  154. /* Special version of aputc() (used by putchar and printf) that filters
  155.  * out nasty characters that screw up the DDOS and ANSI terminal drivers
  156.  */
  157. aputc(c,file)
  158. char c;
  159. FILE *file;
  160. {
  161.     /* Nulls get displayed as spaces by ansi.sys (wrong)
  162.      * ^Z's seem to hang the DoubleDos and DesqView screen drivers
  163.      */
  164.     if((c == '\0' || c == CTLZ) && file == stdout)
  165.         return c;
  166.     /* Do end-of-line translations */
  167.     if(c == '\n')
  168.         putc('\r',file);
  169.     return putc(c,file);
  170. }
  171. /* Reset the CPU, reboot DOS */
  172. sysreset()
  173. {
  174.     int16 regs[8];    /* Not really needed */
  175.  
  176.     farcall(0x0,0xffff,regs,regs);
  177. }
  178.  
  179. /* Install hardware interrupt handler.
  180.  * Takes IRQ numbers from 0-7 (0-15 on AT) and maps to actual 8086/286 vectors
  181.  * Note that bus line IRQ2 maps to IRQ9 on the AT
  182.  */
  183. setirq(irq,handler)
  184. unsigned irq;
  185. void (*handler)();
  186. {
  187.     /* Set interrupt vector */
  188.     if(irq < 8){
  189.         setvect(8+irq,handler);
  190.     } else if(irq < 16){
  191.         isat = 1;
  192.         setvect(0x70 + irq - 8,handler);
  193.     } else {
  194.         return -1;
  195.     }
  196.     return 0;
  197. }
  198. /* Return pointer to hardware interrupt handler.
  199.  * Takes IRQ numbers from 0-7 (0-15 on AT) and maps to actual 8086/286 vectors
  200.  */
  201. void
  202. (*getirq(irq))()
  203. unsigned int irq;
  204. {
  205.     void (*getvect())();
  206.  
  207.     /* Set interrupt vector */
  208.     if(irq < 8){
  209.         return getvect(8+irq);
  210.     } else if(irq < 16){
  211.         return getvect(0x70 + irq - 8);
  212.     } else {
  213.         return NULLVFP;
  214.     }
  215. }
  216. /* Disable hardware interrupt */
  217. maskoff(irq)
  218. unsigned irq;
  219. {
  220.     if(irq < 8){
  221.         setbit(0x21,(char)(1<<irq));
  222.     } else if(irq < 16){
  223.         irq -= 8;
  224.         setbit(0xa1,(char)(1<<irq));
  225.     } else {
  226.         return -1;
  227.     }
  228.     return 0;
  229. }
  230. /* Enable hardware interrupt */
  231. maskon(irq)
  232. unsigned irq;
  233. {
  234.     if(irq < 8){
  235.         clrbit(0x21,(char)(1<<irq));
  236.     } else if(irq < 16){
  237.         irq -= 8;
  238.         clrbit(0xa1,(char)(1<<irq));
  239.     } else {
  240.         return -1;
  241.     }
  242.     return 0;
  243. }
  244. /* Return 1 if specified interrupt is enabled, 0 if not, -1 if invalid */
  245. getmask(irq)
  246. unsigned irq;
  247. {
  248.     if(irq < 8)
  249.         return (inportb(0x21) & (1 << irq)) ? 0 : 1;
  250.     else if(irq < 16){
  251.         irq -= 8;
  252.         return (inportb(0xa1) & (1 << irq)) ? 0 : 1;
  253.     } else
  254.         return -1;
  255. }
  256.